import { AreaData } from '../area';

const viewMode = {
    MOBILE:0,
    PAD:1,
    PC:2
}

//
const thumbType = 
{
    HOTEL:0,
    ROOM: 1,
    ROOM_MODEL:2
}


const rmbFormat = (m, fixed)=>{
    if(fixed){
        return (parseFloat(m)).toFixed(fixed);
    }
    let n = Math.round(100 * parseFloat(m));
    if(isNaN(n)) return '0';
    if(n % 10 !=0) return (n / 100).toFixed(2);
    if(n % 100 !=0) return (n / 100).toFixed(1);
    return (n / 100).toFixed(0);
}

const feeFormat = (m)=>{
    let n = Math.round(10000 * parseFloat(m));
    if(isNaN(n)) return '0';
    if(n % 10 !=0) return (n / 10000).toFixed(4);
    if(n % 100 !=0) return (n / 10000).toFixed(3);
    if(n % 1000 !=0) return (n / 10000).toFixed(2);
    if(n % 10000 !=0) return (n / 10000).toFixed(1);
    return (n / 10000).toFixed(0);
}


const formatNumber = n => { return n > 9 ? n.toString() : '0' + n}
const dateFormat = (number, format) => {
    var formateArr = ['Y', 'M', 'D', 'h', 'm', 's'];
    var date = new Date(number * 1000);
    var returnArr = [
      date.getFullYear(), formatNumber(date.getMonth() + 1), formatNumber(date.getDate()),
      formatNumber(date.getHours()), formatNumber(date.getMinutes()), formatNumber(date.getSeconds())
    ];

    for (var i in returnArr) {
        format = format.replace(formateArr[i], returnArr[i]);
    }
    return format;
}

const timeLimitFormatter = (u, f)=>{
    let harr = [60, 60, 24].map(v=>{
        let r = u % v;
        u = Math.floor(u / v);
        return formatNumber(r);
    });

    if(u > 0){
        harr[harr.length] = formatNumber(u);
    }
    
    let formateArr = ['s','m','h', 'd'];
    let format = f ?? (harr.length == 4?'d h:m:s':'h:m:s');

    for (var i in harr) {
        format = format.replace(formateArr[i], harr[i]);
    }
    return format;
}

const timeLeftFormat = (u)=>{
    if(u > 86400) return '超过1天';
    return timeLimitFormatter(u);
}
const idCardShow = (v)=>{
    if(null ==v || v.length != 18) return '<未填写>';
    return v.substr(0,1) + '**********' + v.substr(12,6);
}

const iCafeStatusStr = v=>{
    switch(v){
    case 0:
        return '正常营业';
    case 1:
        return '营业未办手续';
    case 2:
        return '注销中';
    case 100:
        return '测试场所'
    default:
        return '<营业状态无效>';
    }
}
const iUserRoleStr = v=>['Unknown','老板', '店长', '收银员'][v];



const iAuthModeStr = (v)=>['不要求实名', '用户自主实名','信任万家实名','信任户籍实名','前台的登记实名'][v];

const applyFilters = (data, filters)=>{
    let k, r={};
    for(k in data){
        r[k] = filters[k]?filters[k](data[k]) : data[k]
    }
    return r;
}
const copyObj = function(o) {
    if (null == o || "object" != typeof o)
        return o;
    if(o instanceof Number || o instanceof String || o instanceof Boolean)
        return o.valueOf();

    if (o instanceof Date) {
        var copy = new Date();
        copy.setTime(o.getTime());
        return copy;
    }

    if (o instanceof Object || o instanceof Array) {
        var copy = (o instanceof Array)?[]:{};
        for (var attr in o) {
            if (o.hasOwnProperty(attr))
                copy[attr] = o[attr]?copyObj(o[attr]):o[attr];
        }
        return copy;
    }
    throw new Error("Unable to clone obj! Its type isn't supported.");
}
const sexFormat = (v)=>{
    return v % 2==0 ? '女' : '男'
}

const paySrcFormat = (r)=>{
    return ['现金','微信','支付宝','万家币','计费卡',['计时卡'],'','','','网络支付'][r.src];
}

const micropaySrcFormat = (r)=>{
    let src= {weixin:'微信',alipay:'支付宝',qqpay:'QQ钱包',unionpay:'云闪付', cash:'现金'}
    return src[r] ??'未知';
}
const formatPaytype = (r)=>{
    return ['未知','临时卡','计费卡','计时卡','工作卡'][r] ?? '未知';
}

const getPayCodeType = (code)=>{
    if(/^1[012345]\d{16}$/.test(code)){ //微信: 10~15开头 18位数字
        return 'weixin'
    }else if(/^(2[56789]|30)\d{14,22}$/.test(code)){ //支付宝: 25~30 开头 16~24 长度
        return 'alipay';
    }else if(/^91\d{16}$/.test(code)){ //支付宝: 25~30 开头 16~24 长度
        return 'qqpay';
    }else{
        return 'unionpay'
    }
    return false;
}

/**
 * @param {((resolve: (value: any) => void, reject: (reason?: any) => void,, update: (reason?: any) => void) => void, cancel:() => void} fn 
 * @returns {PromiseEx}
 */
 const PromiseEx = function (fn){
    const me = this;
    let _update = [],  _then = [], _catch = [], p = null, _cancel = null;

    this.then = f=>{_then.push(f); return me}
    this.catch = f=>{_catch.push(f); return me}
    this.update = f=>{_update.push(f); return me}
    this.cancel = ()=>_cancel && _cancel();

    const update = (o)=>_update.forEach(_cb=>_cb(o)), cancel = (cb)=>{ _cancel = cb}

    p = new Promise((r)=>{
        const resolve = (o)=>{
            _then.forEach(_cb=>_cb(o));
            r(o);
        }, reject = (o)=>{
            _catch.forEach(_cb=>_cb(o));
            r(o);
        }
        return fn(resolve, reject, update, cancel)
    });
    return this;
}

const TimerEx = function(fn, interval)
{
    let id = null, ms_ = null;
    this.start = (ms)=>{
        if(null !== id){
            clearInterval(id); id = null;
        }
        ms_ = ms;
        id = setInterval(fn, ms_);
    }
    this.pause = ()=>{
        if(null !== id)clearInterval(id);
        id = null;
    }
    this.resume = ()=>{
        if(null != ms_) this.start(ms_);
    }
    this.clear =()=>{
        if(null !== id)clearInterval(id);
        id = ms_ = null;
    }
    this.start(interval);
    return this;
}

const clone = (x)=>{
    if(x instanceof Object){
        if(x.constructor.name == 'Array'){
            let n = [];
            x.forEach((e,i)=>{
                if(e instanceof Object){
                    n[i] = clone(e)
                }else{
                    n[i] = e
                }
            })
            return n;
        }else{
            let n = {}
            for(var k in x){
                if(x[k] instanceof Object){
                    n[k] = clone(x[k])
                }else{
                    n[k] = x[k]
                }
            }
            return n;
        }
    }
    return n;
}

const isdigit = (c)=>c >= '0' && c <= '9';
/**
 * 生成日期时间范围快捷方式
 * @param {Array<String>} t 可以是 :hour today, prevday, month
 * @returns {Array<Object>}
 */
const timeShortcuts = (t)=>{
    let ret = [];
    if(t.constructor == Array){
        t.forEach(x=>{
            let r, re = /^(\d+|[cp])([dmw])$/;            
            if(null != (r = x.match(re))){
                const o = r[1], u = r[2];
                if(isdigit(o)){
                    let cur = new Date(), prev = new Date(cur.getTime()), x = parseInt(o);
                    cur.setHours(23,59,59,999),prev.setHours(0,0,0,0);
                    switch(u){
                    case 'd':
                        ret.push({text:o + '天内', value:[new Date(prev.getTime() - x * 86400000), cur]})
                        break;
                    case 'm':
                        prev.setFullYear(cur.getFullYear(),cur.getMonth() - x, 1);
                        ret.push({text:o + '月内', value:[prev, cur]})
                        break;
                    case 'w':
                        ret.push({text:o + '周内', value:[new Date(prev.getTime() - x * 7 * 86400000), cur]})
                        break;
                    }
                }else{
                    let cur = new Date(), prev = new Date(cur.getTime());
                    cur.setHours(23,59,59,999),prev.setHours(0,0,0,0);
                    switch(o){
                    case 'c':
                        switch(u){
                        case 'd':
                            ret.push({text:'今天', value:[prev, cur]});
                            break;
                        case 'm':
                            prev.setFullYear(cur.getFullYear(),cur.getMonth(), 1);
                            ret.push({text:'本月', value:[prev, cur]});
                            break;
                        case 'w':
                            if(prev.getDay() == 0){
                                prev.setDate(prev.getDate() - 6);
                            }else{
                                prev.setDate(prev.getDate() - prev.getDay() + 1);
                            }
                            ret.push({text:'本周', value:[prev, cur]});
                            break;
                        }
                        break;
                    case 'p':
                        switch(u){
                        case 'd':
                            cur -= 86400000;prev -= 86400000;
                            ret.push({text:'昨天', value:[prev, cur]})
                            break;
                        case 'm':
                            prev.setFullYear(cur.getFullYear(),cur.getMonth()-1, 1);
                            cur.setFullYear(cur.getFullYear(),cur.getMonth(), 1);
                            ret.push({text:'上月', value:[prev, cur - 86400000]})
                            break;
                        case 'w':
                            if(prev.getDay() == 0){
                                prev.setDate(prev.getDate() - 13);
                            }else{
                                prev.setDate(prev.getDate() - prev.getDay() - 6);
                            }
                            cur = new Date(prev.getTime() + (7 * 86400000 - 1));
                            ret.push({text:'上周', value:[prev, cur]})
                            break;
                        }
                        break;
                    }
                }
            }
        })
    }
    return ret;
}
const todayRange = ()=>{
    let cur = new Date(), prev = new Date(cur.getTime());
    prev.setHours(0,0,0,0),cur.setHours(23,59,59,999)
    return [Math.floor(prev.getTime() / 1000), Math.floor(cur.getTime() / 1000)]
}

const areaSelectData = (selected,area) => {
    var re = /^\d{6}$/;
    
    if(!re.test(selected)){
        return { data:AreaData,selected:[] }
    }

    let res = null,m = [];
    if(selected){
        let pro_code = selected.substr(0,2);
        AreaData.forEach(v => {
            if(v.code == pro_code){
                let city_code = selected.substr(0,4);
                if(area.length == 2){
                    res = [v];
                    m.push(v.code)
                }

                v.children?.forEach(r => {
                    if(r.code == city_code){
                        if(area.length == 2 || area.length == 4)
                            m.push(r.code)
                        
                        if(area.length == 4)
                            res = [r];
                        
                        r.children?.forEach(j => {
                            if(j.code == selected){
                                m.push(j.code)
                                if(area.length == 6){
                                    res = [j];
                                }
                                return
                            }
                        })
                    }
                })
            }
        });
    }

    return {data:res ?? AreaData,selected:res ? m : []};
}

const regionDataPlus = (area) => {
    let res = null;
    if(area){
        let pro_code = area.substr(0,2);
        AreaData.forEach(v => {
            if(v.code == pro_code){
                if(v.code !== area){
                    let city_code = area.substr(0,4);
                    v.children?.forEach(r => {
                        if(r.code == city_code){
                            if(area.length == 4){
                                res = [r];
                                return
                            }else{
                                r.children?.forEach(j => {
                                    if(j.code == area){
                                        res = [j]
                                        return 
                                    }
                                })
                            }
                        }
                    })
                }else{
                    res = [v];
                    return
                }
            }
        });
    }

    return res ?? AreaData;
}

/**
 * 
 * @param {Object} o 要平铺的对象
 */
const objPlat  = function(t, k, o){
    for(var n in o){
        if(o[n] instanceof Object && !(o[n] instanceof Array)){
            objPlat(t, (k==''? '': k + '-') + n, o[n]);
        }else{
            t[ (k==''? '': k + '-') + n] = o[n];
        }
    }
    return t;
}

const deepAssign = function(){
    let tgt = arguments[0];
    for(let i = 1; i < arguments.length; i ++){
        let s = arguments[i];
        for(var k in s){
            let sv = s[k];
            if(!(sv instanceof Array) && (sv instanceof Object)){
                if(tgt[k] instanceof Array || !(sv instanceof Object)){
                    tgt[k] = {};
                }
                tgt[k] = deepAssign(tgt[k] ?? {}, sv);
            }else{
                tgt[k] = sv;
            }
        }
    }
    return tgt;
},
dict = function(arr, key){
    let r = {};
    arr.forEach(v=>{
        r[v[key]] = v;
    })
    return r;
},
dt = [
    {text:'采购', value:0, theme:'success'},
    {text:'出货', value:1 , theme:'danger'},
    {text:'上架', value:2, theme:'primary'},
    {text:'下架', value:3, theme:'warning'},
    {text:'盘点', value:4, theme:'info'},
    {text:'退货', value:5, theme:'danger'},
    {text:'商品整理', value:6, theme:'danger'},
    {text:'货架整理', value:7, theme:'danger'},
    {text:'销售(吧台)', value:8,theme:'success'},
    {text:'销售(客户端)', value:9, theme:'success'},
    {text:'销售(线上)', value:10, theme:'success'},
],
dtD = dict(dt, 'value'),
sm = [
    {text:'挂账', value:0, theme:'danger'},
    {text:'未支付', value:1, theme:'info'},
    {text:'赠送', value:2, theme:'warning'},
    {text:'现金', value:3, theme:'success'},
    {text:'线上', value:4, theme:'primary'},
    {text:'计费卡', value:5, theme:'success'},
],
smD = dict(sm, 'value'),
stg = [
    {text:'预创建', value:0, theme:'info'},
    {text:'待支付', value:1, theme:'info'},
    {text:'已支付', value:2, theme:'success'},
    {text:'待出货', value:3, theme:'info'},
    {text:'已出货', value:4, theme:'success'},
    {text:'已完成', value:5, theme:'success'},
    {text:'已撤销', value:6, theme:'danger'},
], stgD = dict(stg, 'value'),
scene = [
    {text:'吧台', value:1, theme:'success'},
    {text:'客户端', value:2, theme:'primary'},
    {text:'小程序', value:3, theme:'info'},
    {text:'美团', value:4, theme:'info'},
    {text:'饿了么', value:5, theme:'info'},
    {text:'抖音', value:6, theme:'info'},
], sceneD = dict(scene, 'value'),
cos =[
    {value: -1,label: '全部'},
    {value: 0,label: '申请提现'},
    {value: 1,label: '提现成功'},
    {value: 2,label: '提现失败'}
],cosD = dict(cos, 'value'),
calcGoodsFlow = (goods)=>{
    let x, gd = {}; // gd 保存可退款的商品数量
    if(null === goods) goods = [];
    for(x = 0; x < goods.length; x ++){
        // 赠送记录不参与计算
        const g= goods[x];
        if(g.settle_mode != 2){
            let s = g.store_id, i = g.goods_id, num = g.document_type == 5? -g.num : g.num;
            if(!gd[s]) gd[s] = {};
            if(!gd[s][i]) gd[s][i] = num;
            else gd[s][i] += num;
        }
    }
    return goods.filter(g=>g.document_type != 5).map(g=>{
        if(g.settle_mode != 2){
            const s = g.store_id, i = g.goods_id, refund = Math.max(0, g.num - gd[s][i]),allowRefund = Math.max(0, gd[s][i]);
            return {...g, refund, allowRefund};
        }
        // 赠送记录不允许退款
        return {...g, refund:0, allowRefund:0};
    })
};



export {
    viewMode,
    thumbType,
    rmbFormat,
    dateFormat,
    timeLimitFormatter,
    timeLeftFormat,
    idCardShow,
    sexFormat,
    iCafeStatusStr,
    iAuthModeStr,
    iUserRoleStr,
    paySrcFormat,
    applyFilters,
    getPayCodeType,
    micropaySrcFormat,
    formatPaytype,
    copyObj,
    formatNumber,
    feeFormat,
    PromiseEx,
    TimerEx,
    clone,
    dict,
    timeShortcuts,
    todayRange,
    regionDataPlus,
    areaSelectData,
    objPlat,
    deepAssign,
    calcGoodsFlow,
    dt, dtD, sm, smD, stg, stgD, scene, sceneD,cos,cosD
}
